//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package net.mingsoft.basic.aop;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import net.mingsoft.base.entity.ResultData;
import net.mingsoft.base.exception.BusinessException;
import net.mingsoft.base.util.BundleUtil;
import net.mingsoft.basic.bean.UploadConfigBean;
import net.mingsoft.basic.util.BasicUtil;
import net.mingsoft.config.MSProperties;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
@Aspect
public class FileVerifyAop extends BaseAop {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileVerifyAop.class);

    public FileVerifyAop() {
    }

    @Pointcut("execution(* net.mingsoft.basic.action.ManageFileAction.upload(..)) || execution(* net.mingsoft.basic.action.ManageFileAction.uploadTemplate(..))")
    public void uploadPointCut() {
    }

    @Around("uploadPointCut()")
    public Object uploadAop(ProceedingJoinPoint joinPoint) throws Throwable {
        UploadConfigBean bean = (UploadConfigBean)super.getType(joinPoint, UploadConfigBean.class);
        String uploadFileName = FileNameUtil.cleanInvalid(bean.getFile().getOriginalFilename());
        if (StringUtils.isBlank(uploadFileName)) {
            return ResultData.build().error("文件名不能为空!");
        } else {
            InputStream inputStream = bean.getFile().getInputStream();
            String mimeType = BasicUtil.getMimeType(inputStream, uploadFileName);
            if ("zip".equalsIgnoreCase(mimeType)) {
                try {
                    this.checkZip(bean.getFile(), false);
                } catch (Exception var7) {
                    return ResultData.build().error(var7.getMessage());
                }
            }

            return joinPoint.proceed();
        }
    }

    @Around("execution(* net.mingsoft.basic.action.web.FileAction.upload(..))")
    public Object WebUploadAop(ProceedingJoinPoint joinPoint) throws Throwable {
        UploadConfigBean bean = (UploadConfigBean)super.getType(joinPoint, UploadConfigBean.class);
        String uploadFileName = FileNameUtil.cleanInvalid(bean.getFile().getOriginalFilename());
        if (StringUtils.isBlank(uploadFileName)) {
            return ResultData.build().error("文件名不能为空!");
        } else {
            InputStream inputStream = bean.getFile().getInputStream();
            String mimeType = BasicUtil.getMimeType(inputStream, uploadFileName);
            if ("zip".equalsIgnoreCase(mimeType)) {
                try {
                    this.checkZip(bean.getFile(), true);
                } catch (Exception var7) {
                    return ResultData.build().error(var7.getMessage());
                }
            }

            return joinPoint.proceed();
        }
    }

    private void checkZip(MultipartFile multipartFile, boolean isWeb) throws Exception {
        File tempFilePath = FileUtil.mkdir(FileUtil.getTmpDirPath() + "/Zip" + IdUtil.simpleUUID());
        File zipFile = FileUtil.file(tempFilePath.getAbsolutePath() + "/" + IdUtil.simpleUUID() + ".zip");
        InputStream inputStream = multipartFile.getInputStream();
        FileUtils.copyInputStreamToFile(inputStream, zipFile);

        try {
            this.unzip(zipFile, tempFilePath.getAbsolutePath());
            List<File> files = FileUtil.loopFiles(tempFilePath);
            files.remove(zipFile);
            List<String> deniedList = (List)Arrays.stream(MSProperties.upload.denied.split(",")).map(String::toLowerCase).collect(Collectors.toList());
            Iterator var8 = files.iterator();

            while(var8.hasNext()) {
                File file = (File)var8.next();
                FileInputStream fileInputStream = new FileInputStream(file);
                String fileType = FileTypeUtil.getType(file).toLowerCase();
                String fileSuffixName = FileUtil.getSuffix(file);
                if (deniedList.contains(fileSuffixName)) {
                    IOUtils.closeQuietly(fileInputStream);
                    throw new RuntimeException(StrUtil.format("压缩包内文件{}后缀{}禁止上传", new Object[]{file.getName(), fileSuffixName}));
                }

                if (deniedList.contains(fileType)) {
                    IOUtils.closeQuietly(fileInputStream);
                    throw new RuntimeException(StrUtil.format("压缩包内文件{}的类型{}禁止上传", new Object[]{file.getName(), fileType}));
                }

                IOUtils.closeQuietly(fileInputStream);
            }
        } catch (IOException var16) {
            var16.printStackTrace();
        } finally {
            FileUtil.del(tempFilePath);
        }

    }

    private void unzip(File file, String descDir) throws IOException {
        ZipArchiveInputStream inputStream = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(file)));
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }

        ZipArchiveEntry entry = null;

        while((entry = inputStream.getNextZipEntry()) != null) {
            if (entry.getName() == null && (entry.getName().contains("../") || entry.getName().contains("..\\"))) {
                throw new BusinessException(BundleUtil.getString("net.mingsoft.base.resources.resources", "err.error", new String[]{BundleUtil.getString("net.mingsoft.basic.resources.resources", "file.name", new String[0])}));
            }

            String[] dirs = entry.getName().split("/");
            String tempDir = descDir;
            String[] var8 = dirs;
            int var9 = dirs.length;

            for(int var10 = 0; var10 < var9; ++var10) {
                String dir = var8[var10];
                if (dir.indexOf(".") == -1) {
                    tempDir = tempDir + File.separator.concat(dir);
                    FileUtil.mkdir(tempDir);
                }
            }

            if (entry.isDirectory()) {
                File directory = new File(descDir, entry.getName());
                directory.mkdirs();
            } else {
                BufferedOutputStream os = null;

                try {
                    LOGGER.debug("file name => {}", entry.getName());

                    try {
                        os = new BufferedOutputStream(new FileOutputStream(new File(descDir, entry.getName())));
                        IOUtils.copy(inputStream, os);
                    } catch (FileNotFoundException var15) {
                        LOGGER.error("解压{}不存在", entry.getName());
                        var15.printStackTrace();
                    }
                } finally {
                    IOUtils.closeQuietly(os);
                }
            }
        }

        IOUtils.closeQuietly(inputStream);
    }
}
